package com.zd.hamster.client;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 文件上传
 * 
 * @author zhang
 *
 */
public class FileUploader {

	private int cacheSize = 1024;

	/**
	 * 上传（图片压缩） 
	 * @param url
	 * @param in
	 * @param filename
	 * @param maxwidth
	 * @param maxheight
	 * @return
	 * @throws IOException
	 */
	public String up(String url, InputStream in, String filename, int maxwidth, int maxheight) throws IOException {
		url = url.indexOf("?") > -1 ? url : url + "?";
		url += String.format("&picscale=true&maxwidth=%s&maxheight=%s", maxwidth, maxheight);
		return this.up(url, in, filename);
	}

	/**
	 * 上传
	 * 
	 * @param url
	 * @param in
	 * @param filename
	 * @return
	 * @throws IOException
	 */
	public String up(String url, InputStream in, String filename) throws IOException {
		URL u = new URL(url);
		HttpURLConnection conn = null;
		try {
			conn = (HttpURLConnection) u.openConnection();
			String boundary = "----" + UUID.randomUUID();
			setPostParams(conn, boundary);
			uploadFile(conn, in, filename, boundary);
			List<String> result = downloadInfo(conn);
			return result.stream().collect(Collectors.joining());
		} finally {
			conn.disconnect();
		}
	}
	
	/**
	 * 覆盖上传
	 * @param url url中必须包含key键值
	 * @param in
	 * @param filename
	 * @return
	 * @throws IOException
	 */
	public String cover(String url, InputStream in, String filename) throws IOException {
		URL u = new URL(url);
		HttpURLConnection conn = null;
		try {
			conn = (HttpURLConnection) u.openConnection();
			String boundary = "----" + UUID.randomUUID();
			setPutParams(conn, boundary);
			uploadFile(conn, in, filename, boundary);
			List<String> result = downloadInfo(conn);
			return result.stream().collect(Collectors.joining());
		} finally {
			conn.disconnect();
		}
	}
	
	private void setPostParams(HttpURLConnection conn, String boundary) throws IOException {
		this.setParams(conn, boundary, "POST");
	}
	
	private void setPutParams(HttpURLConnection conn, String boundary) throws IOException {
		this.setParams(conn, boundary, "PUT");
	}
	
	private void setParams(HttpURLConnection conn, String boundary, String method) throws IOException {
		conn.setDoInput(true);
		conn.setDoOutput(true);
		conn.setRequestMethod(method);
		conn.setRequestProperty("connection", "Keep-Alive");
//      conn.setRequestProperty("Charsert", "UTF-8");
		conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
		conn.connect();
	}

	private void uploadFile(HttpURLConnection conn, InputStream in, String filename, String boundary)
			throws IOException {
		String boundaryContent = new StringBuilder().append("--").append(boundary).append("\r\n")
				.append("Content-Disposition: form-data;").append(" name=").append("\"file\";").append(" filename=")
				.append("\"").append(filename).append("\"").append("\r\n").append("Content-type: image/jpeg")
				.append("\r\n\r\n").toString();
		try (OutputStream out = conn.getOutputStream()) {
			out.write(boundaryContent.getBytes());
			int len = 0;
			byte[] b = new byte[cacheSize];
			while ((len = in.read(b)) > -1) {
				out.write(b, 0, len);
			}
			out.write(("\r\n--" + boundary + "--\r\n").getBytes());
			out.flush();
		}
	}

	private List<String> downloadInfo(HttpURLConnection conn) throws IOException {
		try (BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
			return reader.lines().collect(Collectors.toList());
		}
	}

	public int getCacheSize() {
		return cacheSize;
	}

	public void setCacheSize(int cacheSize) {
		this.cacheSize = cacheSize;
	}

}
